package main

import (
	"bytes"
	"fmt"
	"gopl/ch5/elementbyid"
	"net/http"
	"os"

	"golang.org/x/net/html"
)

var depth int

func startElement(n *html.Node) {
	if n.Type == html.ElementNode {
		var s bytes.Buffer
		for _, a := range n.Attr {
			fmt.Fprintf(&s, "%s=\"%s\" ", a.Key, a.Val)
		}
		if c := n.FirstChild; c == nil {
			s.WriteByte('/')
		}
		fmt.Printf("%*s<%s %s>\n", depth*2, "", n.Data, s.String())
		depth++
	}
	if n.Type == html.TextNode {
		fmt.Printf("%*s\n", depth*2, n.Data)
		depth++
	}
	if n.Type == html.CommentNode {
		fmt.Printf("%*s\n", depth*2, n.Data)
		depth++
	}
}

func endElement(n *html.Node) {
	if n.Type == html.ElementNode || n.Type == html.TextNode || n.Type == html.CommentNode {
		depth--
		if c := n.FirstChild; c != nil {
			fmt.Printf("%*s</%s>\n", depth*2, "", n.Data)
		}
	}
}

func forEachNode(n *html.Node, pre, post func(n *html.Node)) {
	if pre != nil {
		pre(n)
	}
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		forEachNode(c, pre, post)
	}

	if post != nil {
		post(n)
	}
}

func main() {
	resp, err := http.Get(os.Args[1])
	if err != nil {
		return
	}
	doc, err := html.Parse(resp.Body)
	resp.Body.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "outline: %v\n", err)
		os.Exit(1)
	}
	forEachNode(doc, startElement, endElement)
	n := elementbyid.ElementByID(doc, "ftCon")
	fmt.Println(n)
	fmt.Println(elementbyid.Extend("foo", f))
}

func f(s string) string {
	return fmt.Sprintf("f(s)=%s", s)
}
